import 'package:flutter/material.dart';

/// Dart类型修饰符示例
class TypeModifiersExample extends StatefulWidget {
  const TypeModifiersExample({super.key});

  @override
  State<TypeModifiersExample> createState() => _TypeModifiersExampleState();
}

class _TypeModifiersExampleState extends State<TypeModifiersExample> {
  String result = '点击下方按钮查看类型修饰符示例';

  void _demonstrateFinal() {
    // final - 运行时常量
    final String name = 'Alice';
    final DateTime now = DateTime.now(); // 运行时确定
    final List<int> numbers = [1, 2, 3];

    // numbers = [4, 5, 6]; // ✗ 错误：不能重新赋值
    numbers.add(4); // ✓ 可以：可以修改内容

    setState(() {
      result =
          '''
【final 修饰符】
final表示变量只能赋值一次（运行时常量）。

定义:
final String name = 'Alice';
final DateTime now = DateTime.now();
final List<int> numbers = [1, 2, 3];

特点:
1. 只能赋值一次
   name = 'Bob'; // ✗ 错误

2. 运行时确定值
   final now = DateTime.now(); // ✓ 可以

3. 引用不可变，内容可变
   numbers = [4, 5, 6]; // ✗ 错误：不能重新赋值
   numbers.add(4); // ✓ 可以：可以修改内容
   
   当前numbers: $numbers

使用场景:
• 类的属性（不可变对象）
• 局部变量（只赋值一次）
• 函数参数

class User {
  final String id;    // 一旦创建就不能改
  final String name;
  
  User(this.id, this.name);
}
      ''';
    });
  }

  void _demonstrateConst() {
    // const - 编译时常量
    const String appName = 'Flutter App';
    const int maxUsers = 100;
    const List<String> fruits = ['Apple', 'Banana'];

    // const DateTime now = DateTime.now(); // ✗ 错误：不是编译时常量

    setState(() {
      result = '''
【const 修饰符】
const表示编译时常量，值在编译时就已确定。

定义:
const String appName = 'Flutter App';
const int maxUsers = 100;
const List<String> fruits = ['Apple', 'Banana'];

特点:
1. 编译时就确定值
   const now = DateTime.now(); // ✗ 错误

2. 完全不可变
   const numbers = [1, 2, 3];
   numbers.add(4); // ✗ 错误：无法修改

3. 性能优化
   const Icon(Icons.home); // 编译时创建，重用同一实例
   Icon(Icons.home);       // 每次都创建新实例

4. const构造函数
   const User('Alice'); // 编译时常量对象

Flutter中的应用:
• Widget构造函数推荐使用const
• 减少重建次数
• 提高性能

示例:
const SizedBox(height: 16)  // ✓ 推荐
SizedBox(height: 16)        // 可以但不推荐

const Text('Hello')         // ✓ 推荐
Text('Hello')               // 会重建

const vs final:
• const: 编译时常量，完全不可变
• final: 运行时常量，引用不可变
      ''';
    });
  }

  void _demonstrateStatic() {
    // 使用外部定义的MathUtils类
    double area1 = _MathUtils.calculateCircleArea(5);
    double area2 = _MathUtils.calculateCircleArea(10);

    setState(() {
      result =
          '''
【static 修饰符】
static定义类级别的成员，不属于实例。

class MathUtils {
  static const double pi = 3.14159;
  static int callCount = 0;
  
  static double calculateCircleArea(double radius) {
    callCount++;
    return pi * radius * radius;
  }
}

使用:
// 通过类名访问，不需要实例化
MathUtils.pi // ${_MathUtils.pi}
MathUtils.calculateCircleArea(5) // $area1
MathUtils.calculateCircleArea(10) // $area2
MathUtils.callCount // ${_MathUtils.callCount}

特点:
1. 类级别，所有实例共享
2. 通过类名访问
3. 不能访问实例成员
4. 常用于工具类、常量

常见用法:
class Colors {
  static const Color red = Color(0xFFFF0000);
  static const Color blue = Color(0xFF0000FF);
}

class Validator {
  static bool isEmail(String email) {
    return email.contains('@');
  }
}

使用:
Colors.red
Validator.isEmail('test@example.com')
      ''';
    });
  }

  void _demonstrateVar() {
    // var - 类型推断
    var name = 'Alice'; // 推断为String
    var age = 25; // 推断为int
    var items = ['a', 'b', 'c']; // 推断为List<String>

    // name = 123; // ✗ 错误：类型已确定为String

    setState(() {
      result =
          '''
【var 关键字】
var让Dart自动推断类型。

var name = 'Alice';        // String
var age = 25;              // int
var items = ['a', 'b'];    // List<String>
var map = {'key': 'value'}; // Map<String, String>

特点:
1. 自动类型推断
   var x = 42; // 推断为int
   
2. 类型一旦确定不能改变
   x = 'hello'; // ✗ 错误

3. 必须在声明时初始化
   var y; // ✗ 错误：没有初始值
   
4. 只能用于局部变量
   class User {
     var name = 'Alice'; // ✗ 错误
     String name = 'Alice'; // ✓ 正确
   }

示例:
var name = 'Alice';
print(name.runtimeType); // String

var age = 25;
print(age.runtimeType); // int

当前演示:
name类型: ${name.runtimeType}
age类型: ${age.runtimeType}
items类型: ${items.runtimeType}

何时使用var:
• 类型明显时使用var
• 复杂类型使用var避免重复
• 类属性必须显式声明类型
      ''';
    });
  }

  void _demonstrateLate() {
    setState(() {
      result = '''
【late 修饰符】
late表示延迟初始化，变量会在首次使用前赋值。

1. 延迟初始化非空变量:
late String description;

void init() {
  description = 'Hello'; // 稍后赋值
}

void use() {
  print(description); // 使用前必须已赋值
}

2. 延迟计算:
late String expensiveValue = _computeExpensiveValue();

// _computeExpensiveValue()只在首次访问时调用

3. 循环依赖:
class A {
  late B b = B(this);
}

class B {
  final A a;
  B(this.a);
}

注意事项:
• 使用前必须赋值，否则运行时错误
• 适用于确定会赋值的情况
• 可以延迟昂贵的初始化操作

Flutter中的应用:
class MyWidget extends StatefulWidget {
  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  late AnimationController controller;
  
  @override
  void initState() {
    super.initState();
    controller = AnimationController(...);
  }
}

late vs 可空类型:
• late String name; // 非空，但延迟赋值
• String? name;     // 可空，可以是null
      ''';
    });
  }

  void _demonstrateComparison() {
    setState(() {
      result = '''
【修饰符对比总结】

1. final
   • 运行时常量
   • 只能赋值一次
   • 引用不可变，内容可变
   final list = [1, 2];
   list.add(3); // ✓

2. const
   • 编译时常量
   • 完全不可变
   • 性能优化
   const list = [1, 2];
   list.add(3); // ✗

3. static
   • 类级别成员
   • 所有实例共享
   • 通过类名访问
   static int count = 0;

4. var
   • 自动类型推断
   • 类型确定后不变
   • 局部变量使用
   var name = 'Alice';

5. late
   • 延迟初始化
   • 非空但稍后赋值
   • 首次使用时计算
   late String data;

选择指南:
┌─────────────────┬──────────────┐
│ 场景            │ 使用         │
├─────────────────┼──────────────┤
│ 类的不可变属性  │ final        │
│ 编译时常量      │ const        │
│ Widget构造函数  │ const        │
│ 工具方法/常量   │ static       │
│ 局部变量        │ var/final    │
│ 延迟初始化      │ late         │
└─────────────────┴──────────────┘

最佳实践:
• 优先使用final而不是var
• Widget尽量使用const
• 避免过度使用late
• static用于工具类
      ''';
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Dart 类型修饰符'), backgroundColor: Theme.of(context).colorScheme.inversePrimary),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            // 说明卡片
            Card(
              color: Colors.amber.shade50,
              child: const Padding(
                padding: EdgeInsets.all(16),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text('🔧 类型修饰符概述', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
                    SizedBox(height: 8),
                    Text(
                      'Dart提供多种修饰符控制变量行为：\n'
                      '• final: 运行时常量，只赋值一次\n'
                      '• const: 编译时常量，完全不可变\n'
                      '• static: 类级别成员\n'
                      '• var: 自动类型推断\n'
                      '• late: 延迟初始化',
                      style: TextStyle(fontSize: 14),
                    ),
                  ],
                ),
              ),
            ),
            const SizedBox(height: 16),

            // 代码示例区域
            Container(
              padding: const EdgeInsets.all(16),
              decoration: BoxDecoration(color: Colors.grey.shade200, borderRadius: BorderRadius.circular(8)),
              child: const Text('''// final - 运行时常量
final String name = 'Alice';
final now = DateTime.now();

// const - 编译时常量
const int MAX = 100;
const widget = SizedBox();

// static - 类成员
static const double pi = 3.14;
static int counter = 0;

// var - 类型推断
var age = 25;
var list = [1, 2, 3];

// late - 延迟初始化
late String data;
late final computed = expensive();''', style: TextStyle(fontFamily: 'monospace', fontSize: 13)),
            ),
            const SizedBox(height: 16),

            // 交互按钮
            Wrap(
              spacing: 8,
              runSpacing: 8,
              children: [
                ElevatedButton.icon(onPressed: _demonstrateFinal, icon: const Icon(Icons.lock_outline), label: const Text('final')),
                ElevatedButton.icon(onPressed: _demonstrateConst, icon: const Icon(Icons.lock), label: const Text('const')),
                ElevatedButton.icon(onPressed: _demonstrateStatic, icon: const Icon(Icons.public), label: const Text('static')),
                ElevatedButton.icon(onPressed: _demonstrateVar, icon: const Icon(Icons.auto_awesome), label: const Text('var')),
                ElevatedButton.icon(onPressed: _demonstrateLate, icon: const Icon(Icons.schedule), label: const Text('late')),
                ElevatedButton.icon(onPressed: _demonstrateComparison, icon: const Icon(Icons.compare), label: const Text('对比总结')),
              ],
            ),
            const SizedBox(height: 16),

            // 结果展示区域
            Card(
              elevation: 4,
              child: Container(
                width: double.infinity,
                padding: const EdgeInsets.all(16),
                constraints: const BoxConstraints(minHeight: 150),
                child: Text(result, style: const TextStyle(fontSize: 14, fontFamily: 'monospace')),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

// 辅助类定义
class _MathUtils {
  static const double pi = 3.14159;
  static int callCount = 0;

  static double calculateCircleArea(double radius) {
    callCount++;
    return pi * radius * radius;
  }
}
